package com.ayf.payment.game.api.service.impl;

import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.config.RequestConfig;
import com.ayf.payment.game.api.dto.CreatePartitioneDTO;
import com.ayf.payment.game.api.dto.PartitionChangeDTO;
import com.ayf.payment.game.api.dto.PartitionDTO;
import com.ayf.payment.game.api.dto.criteria.PartitionCriteria;
import com.ayf.payment.game.api.dto.criteria.PartitionPageCriteria;
import com.ayf.payment.game.api.dto.criteria.PartitionSelectCriteria;
import com.ayf.payment.game.api.dto.criteria.TemplateCriteria;
import com.ayf.payment.game.api.entity.*;
import com.ayf.payment.game.api.entity.platform.NetRechargeUrl;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.httpclient.HttpClientUtils;
import com.ayf.payment.game.api.mapper.GroupAndPartitionMapper;
import com.ayf.payment.game.api.mapper.PartitionIdMapper;
import com.ayf.payment.game.api.mapper.PartitionMapper;
import com.ayf.payment.game.api.service.LogOperationService;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.PartitionService;
import com.ayf.payment.game.api.service.TemplateService;
import com.ayf.payment.game.api.service.platform.NetRechargeUrlService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.type.GameCurrencyType;
import com.ayf.payment.game.api.type.Status;
import com.ayf.payment.game.api.type.YesAndNo;
import com.ayf.payment.game.api.utils.CommonResult;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class PartitionServiceImpl implements PartitionService {

    @Resource
    private PartitionMapper partitionMapper;

    @Resource
    private GroupAndPartitionMapper groupAndPartitionMapper;

    @Resource
    private MerchantService merchantService;

    @Resource
    private TemplateService templateService;

    @Autowired
    private NetRechargeUrlService netRechargeUrlService;
    @Autowired
    private WxSendMsgUtils wxSendMsgUtils;
    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Autowired
    private LogOperationService logOperationService;

    @Resource
    PartitionIdMapper partitionIdMapper;

    @Override
    public List<PartitionDTO> selectByDTO(PartitionSelectCriteria selectCriteria) {
        return partitionMapper.selectByDTO(selectCriteria);
    }

    @Override
    public List<PartitionDTO> getPartitionList(PartitionSelectCriteria selectCriteria) {
        return partitionMapper.getPartitionList(selectCriteria);
    }

    @Override
    public void updateByStatus(Partition t) {
        partitionMapper.updateByPrimaryKeySelective(t);
    }

    @Override
    public List<Partition> selectByOpeningTime(PartitionSelectCriteria selectCriteria) {

        return partitionMapper.selectByOpeningTime(selectCriteria);

    }


    @Override
    @Transactional
    public Partition createPartition(PartitionCriteria criteria) {
        try {
            if (criteria == null || StringUtils.isEmpty(criteria.getPartitionName())) {
                throw new ParameterException("参数不能为空");
            }

            PartitionSelectCriteria selectCriteria=new PartitionSelectCriteria();
            selectCriteria.setServiceAgreement(criteria.getServiceAgreement());
            selectCriteria.setPortNum(criteria.getPortNum());
            selectCriteria.setServerIp(criteria.getServerIp());
            selectCriteria.setMerchantId(criteria.getMerchantId());
            CommonResult commonResult= testingWateGay(selectCriteria);
            if(commonResult.getCode()!=200){
                throw new ParameterException("网关不通或通信秘钥错误！");
            }
            if (CollectionUtils.isEmpty(criteria.getGroupAndPartitions())) {
                throw new ParameterException("分组不能为空");
            }

            PartitionId partitionIdAuto = new PartitionId();
            partitionIdMapper.insert(partitionIdAuto);
            String partitionId = String.valueOf(partitionIdAuto.getId());
            criteria.setId(partitionId);
            Partition t = BeanConvertUtils.convert(criteria, Partition.class);
            if(criteria.getOpeningTimeStatus()==1 && StringUtils.isNotEmpty(criteria.getOpeningTime())){
                t.setIsCScript(0);
            }
            t.setCreateTime(new Date());
            t.setLastUpdateTime(new Date());
            partitionMapper.insertSelective(t);
            if (criteria.getPartitionSort() != null){
                if (criteria.getPartitionSort().compareTo(Integer.valueOf(0))<0){
                    throw new ParameterException("分区序号不能小于0");
                }
                Partition upPartition = new Partition();
                upPartition.setId(partitionId);
                upPartition.setLastUpdateTime(DateUtils.getNowDate());
                upPartition.setPartitionSort(criteria.getPartitionSort());
                partitionMapper.updateByPrimaryKeySelective(upPartition);
            }
            t.setId(partitionId);
            criteria.getGroupAndPartitions().forEach((groups) -> {
                groups.setPartitionId(partitionId);
            });
            List<GroupAndPartition> list = BeanConvertUtils.convert(criteria.getGroupAndPartitions(), GroupAndPartition.class);
            groupAndPartitionMapper.insertBatch(list);
            LogOperation logOperation=new LogOperation("创建分区","分区名："+criteria.getPartitionName(),"成功", new Date(),criteria.getMerchantId(),t.getId());
            logOperationService.insert(logOperation);
            return t;
        } catch (ParameterException e) {
            throw e;
        } catch (Exception e) {
            LogOperation logOperation=new LogOperation("创建分区","分区名："+criteria.getPartitionName(),"失败", new Date(),criteria.getMerchantId(),"");
            logOperationService.insert(logOperation);
            LogPortal.info("保存分区失败 商户ID[{}] 分区名:{}",e, criteria.getMerchantId(),criteria.getPartitionName() );
            throw new ParameterException("保存分区失败");
        }
   }


    @Override
    @Transactional
    public boolean updatePartition(PartitionCriteria criteria) {
       try {
           Partition t = BeanConvertUtils.convert(criteria, Partition.class);
           if (t == null) {
               throw new ParameterException("参数不能为空");
           }
           if (StringUtils.isEmpty(t.getPartitionName())) {
               throw new ParameterException("分区名称不能为空");
           }
           PartitionSelectCriteria selectCriteria=new PartitionSelectCriteria();
           selectCriteria.setServiceAgreement(criteria.getServiceAgreement());
           selectCriteria.setPortNum(criteria.getPortNum());
           selectCriteria.setServerIp(criteria.getServerIp());
           selectCriteria.setMerchantId(criteria.getMerchantId());
           CommonResult commonResult= testingWateGay(selectCriteria);
           if(commonResult.getCode()!=200){
               throw new ParameterException("网关不通或通信秘钥错误！");
           }
           t.setLastUpdateTime(new Date());
           if (criteria.getPartitionSort() != null) {
               if (criteria.getPartitionSort().compareTo(Integer.valueOf(0)) < 0) {
                   throw new ParameterException("分区序号不能小于0");
               }
           }
           partitionMapper.updatePartition(t);
           groupAndPartitionMapper.delPartitionAndGroup(t.getId());

           if (CollectionUtils.isEmpty(criteria.getGroupAndPartitions())) {
               throw new ParameterException("分组不能为空");
           }
           criteria.getGroupAndPartitions().forEach((groups) -> {
               groups.setPartitionId(t.getId());
           });
           List<GroupAndPartition> list = BeanConvertUtils.convert(criteria.getGroupAndPartitions(), GroupAndPartition.class);
           groupAndPartitionMapper.insertBatch(list);
           LogOperation logOperation=new LogOperation("更新分区","分区名："+criteria.getPartitionName(),"成功", new Date(),criteria.getMerchantId(),criteria.getId());
           logOperationService.insert(logOperation);
           return true;
       } catch (ParameterException e) {
           throw e;
       } catch (Exception e) {
           LogOperation logOperation=new LogOperation("更新分区","分区名:"+criteria.getPartitionName(),"失败", new Date(),criteria.getMerchantId(),criteria.getId());
           logOperationService.insert(logOperation);
           LogPortal.info("修改分区失败 商户ID[{}] 分区名:{}",e, criteria.getId(),criteria.getPartitionName() );
          throw new IllegalArgumentException("修改分区失败");
      }
    }

    public PartitionChangeDTO selectPartitionChangeDTO(Integer merchantId, String partitionId) {
        Map map = new HashMap();
        map.put("merchantId", merchantId);
        map.put("partitionId", partitionId);
        return partitionMapper.selectPartitionChangeDTO(map);
    }

    @Override
    @Transactional
    public String clonePartition(Integer merchantId, String partitionId) {
        Map map = new HashMap();
        map.put("merchantId", merchantId);
        map.put("partitionId", partitionId);
        PartitionCriteria criteria = partitionMapper.selectPartitionCriteria(map);
        Partition partition = new Partition();
        partition.setLastUpdateTime(criteria.getLastUpdateTime());
        partition.setGameInfoId(criteria.getGameInfoId());
        partition.setOpeningTimeStatus(0);
        partition.setOpeningTime("");
        partition.setServiceAgreement(criteria.getServiceAgreement());
        partition.setCreateTime(new Date());
        partition.setTreasureOn(criteria.getTreasureOn());
        partition.setTemplateId(criteria.getTemplateId());
        partition.setServerIp(criteria.getServerIp());
        partition.setPartitionStatus(criteria.getPartitionStatus());
        partition.setPartitionName("克隆_"+criteria.getPartitionName());
        partition.setMerchantId(criteria.getMerchantId());
        partition.setIsCScript(0);
        partition.setInstallPath(criteria.getInstallPath());
        partition.setChangeTime(criteria.getChangeTime());
        partition.setChangeName(criteria.getChangeName());
        partition.setPortNum(criteria.getPortNum());
        partitionMapper.insert(partition);
        List<GroupAndPartition> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(criteria.getGroupAndPartitions())) {
            criteria.getGroupAndPartitions().forEach((gp) -> {
                GroupAndPartition groupAndPartition = new GroupAndPartition();
                groupAndPartition.setGroupsId(gp.getGroupsId());
                groupAndPartition.setGroupName(gp.getGroupName());
                groupAndPartition.setPartitionId(partition.getId());
                list.add(groupAndPartition);
            });
            groupAndPartitionMapper.insertBatch(list);
        }
        return  partition.getId();
    }

    @Override
    public CommonResult loadPartition(Integer merchantId, String partitionId, int isClean,String operIp) {
        String traceId = SnowFlakeUtils.getTraceId();
        List<NetRechargeUrl> netRechargeUrlList = netRechargeUrlService.selectAll();
        if (CollectionUtils.isEmpty(netRechargeUrlList)){
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "充值站点地址不存在，请联系技术支持", "");
        }
        Merchant merchant = merchantService.find(merchantId);
        PartitionChangeDTO partition = selectPartitionChangeDTO(merchant.getId(), partitionId);
        try {
            TemplateCriteria template = templateService.selectTemById(partition.getTemplateId());
            if (GameCurrencyType.RMB.equals(template.getGameCurrencyType())){
                template.setGameCurrencyType(GameCurrencyType.CUSTOM);
            }
            CreatePartitioneDTO cpDTO = new CreatePartitioneDTO();
            cpDTO.setPartition(partition);
            cpDTO.setTemplate(template);
            cpDTO.setIsClean(isClean);

            List<Map<String,String>> payUrlList = new ArrayList<>(netRechargeUrlList.size());
            netRechargeUrlList.forEach(item->{
                Map<String,String> payUrl = new HashMap<>();
                payUrl.put(item.getNetName(),getRechargeUrl(partitionId,item.getUrl()));
                payUrlList.add(payUrl);
            });
            cpDTO.setPayUrl(payUrlList);
            String url = cpDTO.getPartition().getServiceAgreement() + "://" + cpDTO.getPartition().getServerIp() + ":" + cpDTO.getPartition().getPortNum();
            CommonResult result = HttpClientUtils.doPostGetWay(url + RequestConfig.GETWAY_LOAD_PARTITION_URL, cpDTO,
                    merchant.getPrivateKey(),traceId);
            switch(result.getCode()){
                case 200 :
                    LogPortal.error("{} 创建分区脚本成功 分区ID:[{}]--[{}]，msg : [{}]",traceId,partitionId,partition.getPartitionName(), result.getMsg());
                    if (isClean == 0) {
                        LogOperation logOperation = new LogOperation("创建分区脚本", "创建分区脚本成功(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "成功", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    } else {
                        LogOperation logOperation = new LogOperation("加载分区脚本", "加载分区脚本成功(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "成功", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    }
                    Partition t = new Partition();
                    t.setId(partitionId);
                    t.setOpeningTimeStatus(2);
                    t.setIsCScript(1);

                    updateByStatus(t);
                    result.setMsg("创建成功");
                    break;
                case -1 :
                    LogPortal.error("{} LOAD_PARTITION_RETRUN_FAIL 创建分区脚本失败 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    result.setMsg("创建分区脚本失败:"+result.getMsg());
                    sendWxMsg(traceId, merchantId, partitionId, result.getMsg());
                    if (isClean == 0) {
                        LogOperation logOperation = new LogOperation("创建分区脚本", "创建分区脚本失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    } else {
                        LogOperation logOperation = new LogOperation("加载分区脚本", "加载分区脚本失(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    }
                    break;
                case 800 :
                    LogPortal.error("{} SEND_GATEWAY_LOAD_PARTITION_CONNECT_TIMEOUT_FAIL 创建分区脚本连接超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    result.setMsg("网关连接超时创建失败!");
                    sendWxMsg(traceId, merchantId, partitionId, result.getMsg());
                    if (isClean == 0) {
                        LogOperation logOperation = new LogOperation("创建分区脚本", "网关连接超时创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    } else {
                        LogOperation logOperation = new LogOperation("加载分区脚本", "网关连接超时创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    }
                    break;
                case 801 :
                    LogPortal.error("{} SEND_GATEWAY_LOAD_PARTITION_SOCKET_TIMEOUT_FAIL 创建分区脚本SOCKET超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    result.setMsg("网关SOCKET超时创建失败!");
                    sendWxMsg(traceId, merchantId, partitionId, result.getMsg());
                    if (isClean == 0) {
                        LogOperation logOperation = new LogOperation("创建分区脚本", "网关SOCKET超时创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    } else {
                        LogOperation logOperation = new LogOperation("加载分区脚本", "网关SOCKET超时创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    }
                    break;
                case 802 :
                    LogPortal.error("{} SEND_GATEWAY_LOAD_PARTITION_EXCEPTION_FAIL 创建分区脚本异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    result.setMsg("网关连接异常创建失败!");
                    sendWxMsg(traceId, merchantId, partitionId, result.getMsg());
                    if (isClean == 0) {
                        LogOperation logOperation = new LogOperation("创建分区脚本", "网关连接异常创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    } else {
                        LogOperation logOperation = new LogOperation("加载分区脚本", "网关连接异常创建失败(" + cpDTO.getPartition().getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                        logOperationService.insert(logOperation);
                    }
                    break;
                default:
            }
            return result;
        } catch (ConnectTimeoutException e) {
            LogPortal.error("{} LOAD_PARTITION_EXCEPTION_FAIL 加载分区时连接超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId, merchantId, partitionId, partition.getPartitionName(), e.getMessage());
            LogPortal.error("{} 加载分区时连接超时 商户ID[{}] 分区ID:[{}]--[{}]", e, traceId, merchantId, partitionId,
                    partition.getPartitionName());
            String key = "CREATE_PARTITION_FAIL:" + partitionId;
            int val = redisCacheUtil.getObjectFromCache(key);
            redisCacheUtil.setObjectToCache(key, val + 1, 1L, TimeUnit.DAYS);
            if (val == 4) {
                wxSendMsgUtils.createPartitionFail(traceId, merchantId, "加载分区时连接超时次数已经超过5次，请检查分区信息", partitionId);
            }
        } catch (HttpHostConnectException e) {
            LogPortal.error("{} LOAD_PARTITION_EXCEPTION_FAIL 加载创建分区连接被拒绝，请检查网关是否开启 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : " +
                            "[{}]",traceId, merchantId, partitionId, partition.getPartitionName(), e.getMessage());
            LogPortal.error("{} 加载创建分区连接接被拒绝，请检查网关是否开启 商户ID[{}] 分区ID:[{}]--[{}]", e, traceId, merchantId, partitionId,
                    partition.getPartitionName());

            sendWxMsg(traceId, merchantId, partitionId, "加载创建分区连接接被拒绝，请检查网关是否开启");
        } catch (Exception e) {
            LogPortal.error("{} LOAD_PARTITION_EXCEPTION_FAIL 加载创建分区发生异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]", traceId, merchantId, partitionId, partition.getPartitionName(), e.getMessage());
            LogPortal.error("{} 加载创建分区发生异常 商户ID[{}] 分区ID:[{}]--[{}]", e, traceId, merchantId, partitionId, partition.getPartitionName());

            sendWxMsg(traceId, merchantId, partitionId, "加载创建分区发生" + e.getClass().getSimpleName() + "异常，异常信息为" + e.getMessage());
            if (isClean == 0) {
                LogOperation logOperation = new LogOperation("创建分区脚本", "创建分区发生失败(" + partition.getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                logOperationService.insert(logOperation);
            } else {
                LogOperation logOperation = new LogOperation("加载分区脚本", "加载分区发生失败(" + partition.getPartitionName() + ")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                logOperationService.insert(logOperation);
            }
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "分区脚本创建失败!", "");
    }

    private void sendWxMsg(String traceId, Integer merchantId, String partitionId, String first) {
        String key = "CREATE_PARTITION_FAIL:" + partitionId;
        String redisPartitionId = redisCacheUtil.getObjectFromCache(key);
        if (StringUtils.isEmpty(redisPartitionId)) {
            redisCacheUtil.setObjectToCache(key, partitionId, 1L, TimeUnit.DAYS);
            wxSendMsgUtils.createPartitionFail(traceId, merchantId, first, partitionId);
        }
    }

    private String getRechargeUrl(String partitionId,String orginUrl) {
        String url = orginUrl;
        if (!url.endsWith("/")) {
            url = url.concat("/");
        }
        url = url.concat("gws/index.html?pid=").concat(partitionId);
        return url;
    }

    @Override
    public boolean cleanDataPartition(Integer merchantId, String partitionId,String operIp) {
        String traceId = SnowFlakeUtils.getUniqueId();
        Merchant merchant = merchantService.find(merchantId);
        PartitionChangeDTO partition = selectPartitionChangeDTO(merchant.getId(), partitionId);
        try {
            TemplateCriteria template = templateService.selectTemById(partition.getTemplateId());
            CreatePartitioneDTO cpDTO = new CreatePartitioneDTO();
            cpDTO.setPartition(partition);
            cpDTO.setTemplate(template);
            String url = cpDTO.getPartition().getServiceAgreement() + "://" + cpDTO.getPartition().getServerIp() + ":" + cpDTO.getPartition().getPortNum();
            CommonResult result = HttpClientUtils.doPostGetWay(url + RequestConfig.GETWAY_CLEANDATA_PARTITION_URL,
                    cpDTO, merchant.getPrivateKey(),traceId);
            boolean isOk=true;
            switch(result.getCode()){
                case 200 :
                    LogOperation logOperation = new LogOperation("清空分区", "分区名("+cpDTO.getPartition().getPartitionName()+")，操作IP:"+operIp, "成功", new Date(), merchantId, partitionId);
                    logOperationService.insert(logOperation);
                    LogPortal.error("{} 清空分区脚本数据成功 分区ID:[{}]--[{}]，msg : [{}]",traceId,partitionId,partition.getPartitionName(), result.getMsg());
                    break;
                case -1 :
                    logOperation = new LogOperation("清空分区", "清空分区脚本数据失败("+cpDTO.getPartition().getPartitionName()+")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                    logOperationService.insert(logOperation);
                    LogPortal.error("{} SEND_GATEWAY_CLEANDATA_PARTITION_RETRUN_FAIL 清空分区脚本数据失败 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    isOk=false;
                    break;
                case 800 :
                    logOperation = new LogOperation("清空分区", "清空分区脚本数据连接超时("+cpDTO.getPartition().getPartitionName()+")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                    logOperationService.insert(logOperation);
                    LogPortal.error("{} SEND_GATEWAY_CLEANDATA_PARTITION_CONNECT_TIMEOUT_FAIL 清空分区脚本数据连接超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    isOk=false;
                    break;
                case 801 :
                    LogPortal.error("{} SEND_GATEWAY_CLEANDATA_PARTITION_SOCKET_TIMEOUT_FAIL 清空分区脚本数据SOCKET超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    isOk=false;
                    break;
                case 802 :
                    logOperation = new LogOperation("清空分区", "清空分区脚本数据异常("+cpDTO.getPartition().getPartitionName()+")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
                    logOperationService.insert(logOperation);
                    LogPortal.error("{} SEND_GATEWAY_CLEANDATA_PARTITION_EXCEPTION_FAIL 清空分区脚本数据异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(),result.getMsg());
                    isOk=false;
                    break;
                default:
            }
            return isOk;
        } catch (Exception e) {
            LogOperation logOperation = new LogOperation("清空分区", "加载清空分区脚本数据失败("+partition.getPartitionName()+")，操作IP:"+operIp, "失败", new Date(), merchantId, partitionId);
            logOperationService.insert(logOperation);
            LogPortal.error("{} CLEANDATA_PARTITION_EXCEPTION_FAIL 加载清空分区脚本数据发生异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,merchantId,partitionId,partition.getPartitionName(), e.getMessage());
            LogPortal.error("{} 加载清空分区脚本数据发生异常 商户ID[{}] 分区ID:[{}]--[{}]",e,traceId,merchantId,partitionId,partition.getPartitionName());
        }
        return false;
    }

    @Override
    public CommonResult testingWateGay(PartitionSelectCriteria selectCriteria) {
        String traceId = SnowFlakeUtils.getUniqueId();
        PartitionChangeDTO partition =new PartitionChangeDTO();
        if(StringUtils.isNotEmpty(selectCriteria.getPartitionId())) {
             partition = selectPartitionChangeDTO(selectCriteria.getMerchantId(), selectCriteria.getPartitionId());
        }else{
            partition.setServiceAgreement(selectCriteria.getServiceAgreement());
            partition.setServerIp(selectCriteria.getServerIp());
            partition.setPortNum(selectCriteria.getPortNum());
        }
        try {

            Merchant merchant = merchantService.find(selectCriteria.getMerchantId());
            String url = partition.getServiceAgreement() + "://" + partition.getServerIp() + ":" + partition.getPortNum();
            CommonResult result = HttpClientUtils.doPostGetWay(url + RequestConfig.GETWAY_TESTING_URL, partition,
                    merchant.getPrivateKey(),traceId,5);
            switch(result.getCode()){
                case 200 :
                    LogPortal.error("{} 检测分区成功 商户ID[{}] 分区ID:[{}]--[{}]，msg : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(), result.getMsg());
                    break;
                case -1 :
                    LogPortal.error("{} TESTING_PARTITION_RETRUN_FAIL 检测分区失败 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(),result.getMsg());
                    break;
                case 800 :
                    LogPortal.error("{} SEND_GATEWAY_TESTING_PARTITION_CONNECT_TIMEOUT_FAIL 检测分区连接超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(),result.getMsg());
                    break;
                case 801 :
                    LogPortal.error("{} SEND_GATEWAY_TESTING_PARTITION_SOCKET_TIMEOUT_FAIL 检测分区SOCKET超时 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(),result.getMsg());
                    break;
                case 802 :
                    LogPortal.error("{} SEND_GATEWAY_TESTING_PARTITION_EXCEPTION_FAIL 检测分区异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(),result.getMsg());
                    break;
                default:
            }
            return result;
        } catch (Exception e) {
            LogPortal.error("{} TESTING_PARTITION_EXCEPTION_FAIL 检测分区异常 商户ID[{}] 分区ID:[{}]--[{}]，失败描述 : [{}]",traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName(),e.getMessage());
            LogPortal.error("{} 检测分区异常 商户ID[{}] 分区ID:[{}]--[{}]",e,traceId,selectCriteria.getMerchantId(),partition.getId(),partition.getPartitionName());
        }
           return new CommonResult(CommonConstants.RETURN_ERROR, "检测失败", "");
    }

    @Override
    public void delete(Partition t) {
        t.setPartitionStatus(Status.PROHIBIT);
        t.setLastUpdateTime(DateUtils.getNowDate());
        partitionMapper.updateByPrimaryKeySelective(t);
        LogOperation logOperation = new LogOperation("删除分区", "分区名："+t.getPartitionName()+"，操作IP:"+t.getOperIp(), "成功", new Date(), t.getMerchantId(), t.getId());
        logOperationService.insert(logOperation);
    }

    @Override
    public Partition find(Integer merchantId, String partitionId) {
        Partition p = new Partition();
        p.setMerchantId(merchantId);
        p.setId(partitionId);
        return partitionMapper.selectOne(p);
    }

    @Override
    public void save(Partition t) {
        partitionMapper.insert(t);
    }

    @Override
    public boolean isHavePartitionByTemId(String temId) {
        if (StringUtils.isEmpty(temId)) {
            throw new ParameterException("模板id不能为空");
        }
        Partition partition = new Partition();
        partition.setTemplateId(temId);
        partition.setPartitionStatus(Status.ENABLE);
        List<Partition> partitionList = partitionMapper.select(partition);
        return partitionList != null && partitionList.size() > 0;
    }

    @Override
    public boolean isHavePartitionById(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new ParameterException("id不能为空");
        }
        return partitionMapper.selectByPrimaryKey(id) != null;
    }

    @Override
    public boolean updatePartitionName(Partition partition) {
        if (partition == null || partition.getChangeTime() == null) {
            throw new ParameterException("当前时间不能为空");
        }
        return partitionMapper.updatePartitionName(partition) > 0;
    }

    @Override
    public List<PartitionDTO> selectPartitionInfo(PartitionCriteria criteria) {
        if (criteria == null || criteria.getMerchantId() == null) {
            return null;
        }
        if (StringUtils.isNotEmpty(criteria.getGroupId())) {
            List<PartitionDTO> dto = partitionMapper.selectPartitionByGroupId(criteria.getGroupId(),DateUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss"));
            return dto;
        }
        List<Partition> db = partitionMapper.selectEnablePartitionList(criteria.getMerchantId(),DateUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss"));
        List<PartitionDTO> dto = BeanConvertUtils.convert(db, PartitionDTO.class);
        return dto;
    }

    @Override
    public List<PartitionDTO> selectByPage(PartitionPageCriteria selectCriteria) {
        return  partitionMapper.selectByPageDTO(selectCriteria);
    }

    @Override
    public void updatePartitionSort(PartitionCriteria criteria) {
        if (StringUtils.isEmpty(criteria.getPartitionId())){
            throw new ParameterException("分区ID不能为空");
        }
        if (criteria.getPartitionSort() == null || criteria.getPartitionSort().compareTo(Integer.valueOf(0))<0){
            throw new ParameterException("分区序号不能为空值且不能小于0");
        }
        Partition partition = new Partition();
        partition.setLastUpdateTime(DateUtils.getNowDate());
        partition.setPartitionSort(criteria.getPartitionSort());
        partition.setId(criteria.getPartitionId());
        partitionMapper.updateByPrimaryKeySelective(partition);
    }

    @Override
    public PartitionDTO getPartitionInfoById(String partitionId) {
        return BeanConvertUtils.convert(partitionMapper.selectByPrimaryKey(partitionId), PartitionDTO.class);
    }

    @Override
    public int selectPartSum(Integer merchantId) {
        if (merchantId == null) {
            throw new ParameterException("商户id不能为空");
        }
        return partitionMapper.selectPartSum(merchantId);
    }

    @Override
    public List<PartitionDTO> selectByGameId(PartitionSelectCriteria selectCriteria) {
        return partitionMapper.selectByGameId(selectCriteria);
    }

    @Override
    public List<String> selectGameCurrencyName(Integer merchantId) {
        return partitionMapper.selectGameCurrencyName(merchantId);
    }

    @Override
    public List<Partition> selectByChangeNameTime(PartitionSelectCriteria selectCriteria) {
        return partitionMapper.selectByChangeNameTime(selectCriteria);
    }

    @Override
    public void updateByName(Partition t) {
        t.setPartitionName(t.getChangeName());
        t.setIsChangeName(YesAndNo.NO);
        t.setLastUpdateTime(new Date());
        partitionMapper.updateByPrimaryKeySelective(t);
    }

}


